import {
  type Component,
  createMemo,
  createSignal,
  Index,
  mergeProps,
  Show,
} from "solid-js";
import type { PaginationProps } from "./types";
import type { RouteDefinition } from "@solidjs/router";

const defaultProps: Partial<PaginationProps> = {
  sizeList: [],
  totalCount: 0,
  defaultSize: 20,
  pagerCount: 7,
};

const Pagination: Component<PaginationProps> = (p) => {
  const props = mergeProps(defaultProps, p);

  const [_current, _setCurrent] = createSignal<PaginationProps["current"]>({
    page: 1,
    size: props.defaultSize!,
  });

  const classList = createMemo(() => {
    return {
      "pagination-sm": props.size === "sm",
      "pagination-lg": props.size === "lg",
      ...props.classList,
    };
  });

  const currentState = createMemo(() => {
    return props.current ?? _current();
  });

  const totalPagesCount = createMemo(() => {
    return (props.totalCount ?? 0) <= 0
      ? 1
      : Math.ceil(props.totalCount! / currentState()!.size);
  });

  const updateState = (page: number, size: number) => {
    if (props.current === undefined) {
      _setCurrent({
        page,
        size,
      });
    }

    props.onChanged?.(page, size);
  };

  const gotoPage = (page: number) => {
    updateState(page, currentState()!.size);
  };

  const gotoFirst = () => {
    updateState(1, currentState()!.size);
  };

  const gotoLast = () => {
    updateState(totalPagesCount(), currentState()!.size);
  };

  const gotoNext = () => {
    const { page, size } = currentState()!;

    if (totalPagesCount() > page) {
      updateState(page + 1, size);
    }
  };

  const gotoPrevious = () => {
    const { page, size } = currentState()!;

    if (page > 1) {
      updateState(page - 1, size);
    }
  };

  const disabledGotoPrevious = createMemo(() => {
    return currentState()!.page <= 1;
  });

  const disabledGotoNext = createMemo(() => {
    return currentState()!.page >= totalPagesCount();
  });

  const pages = createMemo(() => {
    const numbers = Array.from({ length: totalPagesCount() }).map(
      (_, index) => {
        return index + 1;
      }
    );

    const total = totalPagesCount();

    const current = currentState()!.page;
    const prev = current - 1 - 1 < 0 ? 0 : current - 1 - 1;
    const next = total - current - 1 < 0 ? 0 : total - current - 1;

    const fixed = current === 1 || current === total ? 2 : 3;

    const pCount = Math.floor((props.pagerCount! - fixed) / 2);
    const pc = pCount > prev ? prev : pCount;
    let pStart = pCount > prev ? 2 : current - pCount;

    const nCount = props.pagerCount! - fixed - pc;
    const nEnd = nCount > next ? total - 1 : current + nCount;
    if (total > props.pagerCount! && pStart > total - props.pagerCount! + 1) {
      pStart = total - props.pagerCount! + 1;
    }

    const pages: { page?: number; label: string }[] = [];
    pages.push({ page: 1, label: "1" });

    const zipPrev = prev > pCount;
    const zipNext = next > nCount;

    if (zipPrev) {
      pages.push({ label: "..." });
    }

    numbers.forEach((n) => {
      if (pStart <= n && n <= nEnd) {
        pages.push({ page: n, label: `${n}` });
      }
    });

    if (zipNext) {
      pages.push({ label: "..." });
    }

    if (total > 1) {
      pages.push({ page: total, label: `${total}` });
    }

    return pages;
  });

  const isActive = (page: number) => {
    return page === currentState()!.page;
  };

  return (
    <ul class="pagination" classList={classList()}>
      <Show when={props.showTotal}>
        <li class="page-item ">
          <span class="page-link disabled">Total: {props.totalCount ?? 0}</span>
        </li>
      </Show>
      <li class="page-item" classList={{ disabled: disabledGotoPrevious() }}>
        <a class="page-link" href="javascript:void(0)" onclick={gotoPrevious}>
          上一页
        </a>
      </li>
      <Index each={pages()}>
        {(page, _) => (
          <li
            class="page-item"
            classList={{
              active: page().page !== undefined && isActive(page().page!),
            }}
          >
            {page().page !== undefined ? (
              <a
                class="page-link"
                href="javascript:void(0)"
                onclick={() => gotoPage(page().page!)}
              >
                {page().label}
              </a>
            ) : (
              <span class="page-link">{page().label}</span>
            )}
          </li>
        )}
      </Index>
      <li class="page-item" classList={{ disabled: disabledGotoNext() }}>
        <a class="page-link" href="javascript:void(0)" onclick={gotoNext}>
          下一页
        </a>
      </li>
    </ul>
  );
};

export default Pagination;
